using UnityEngine;
using UnityEngine.Rendering;
using static UnityEngine.ParticleSystem;
using System.Collections.Generic;
using System;

[Serializable]
public class ParticleDummyData
{
    public float time;
    public uint randomSeed;
    public bool useAutoRandomSeed;
    public MainModule main;
    public EmissionModule emission;
    public ShapeModule shape;
    public VelocityOverLifetimeModule velocityOverLifetime;
    public LimitVelocityOverLifetimeModule limitVelocityOverLifetime;
    public InheritVelocityModule inheritVelocity;
    public LifetimeByEmitterSpeedModule lifetimeByEmitterSpeed;
    public ForceOverLifetimeModule forceOverLifetime;
    public ColorOverLifetimeModule colorOverLifetime;
    public ColorBySpeedModule colorBySpeed;
    public SizeOverLifetimeModule sizeOverLifetime;
    public SizeBySpeedModule sizeBySpeed;
    public RotationOverLifetimeModule rotationOverLifetime;
    public RotationBySpeedModule rotationBySpeed;
    public ExternalForcesModule externalForces;
    public NoiseModule noise;
    public CollisionModule collision;
    public TriggerModule trigger;
    public SubEmittersModule subEmitters;
    public TextureSheetAnimationModule textureSheetAnimation;
    public LightsModule lights;
    public TrailModule trails;
    public CustomDataModule customData;
    public Renderer renderer;

    [Serializable]
    public struct MainModule
    {
        public float duration;
        public bool loop;
        public bool prewarm;
        public MinMaxCurve startDelay;
        public float startDelayMultiplier;
        public MinMaxCurve startLifetime;
        public float startLifetimeMultiplier;
        public MinMaxCurve startSpeed;
        public float startSpeedMultiplier;
        public bool startSize3D;
        public MinMaxCurve startSize;
        public float startSizeMultiplier;
        public MinMaxCurve startSizeX;
        public float startSizeXMultiplier;
        public MinMaxCurve startSizeY;
        public float startSizeYMultiplier;
        public MinMaxCurve startSizeZ;
        public float startSizeZMultiplier;
        public bool startRotation3D;
        public MinMaxCurve startRotation;
        public float startRotationMultiplier;
        public MinMaxCurve startRotationX;
        public float startRotationXMultiplier;
        public MinMaxCurve startRotationY;
        public float startRotationYMultiplier;
        public MinMaxCurve startRotationZ;
        public float startRotationZMultiplier;
        public float flipRotation;
        public MinMaxGradient startColor;
        public MinMaxCurve gravityModifier;
        public float gravityModifierMultiplier;
        public ParticleSystemSimulationSpace simulationSpace;
        public Transform customSimulationSpace;
        public float simulationSpeed;
        public bool useUnscaledTime;
        public ParticleSystemScalingMode scalingMode;
        public bool playOnAwake;
        public int maxParticles;
        public ParticleSystemEmitterVelocityMode emitterVelocityMode;
        public ParticleSystemStopAction stopAction;
        public ParticleSystemRingBufferMode ringBufferMode;
        public Vector2 ringBufferLoopRange;
        public ParticleSystemCullingMode cullingMode;
    }

    [Serializable]
    public struct EmissionModule
    {
        public bool enabled;
        public MinMaxCurve rateOverTime;
        public float rateOverTimeMultiplier;
        public MinMaxCurve rateOverDistance;
        public float rateOverDistanceMultiplier;
        public int burstCount;
        public Burst[] bursts;
    }

    [Serializable]
    public struct Burst
    {
        public float time;
        public MinMaxCurve count;
        public int cycleCount;
        public float repeatInterval;
        public float probability;
    }

    [Serializable]
    public struct ShapeModule
    {
        public bool enabled;
        public ParticleSystemShapeType shapeType;
        public float randomDirectionAmount;
        public float sphericalDirectionAmount;
        public float randomPositionAmount;
        public bool alignToDirection;
        public float radius;
        public ParticleSystemShapeMultiModeValue radiusMode;
        public float radiusSpread;
        public MinMaxCurve radiusSpeed;
        public float radiusSpeedMultiplier;
        public float radiusThickness;
        public float angle;
        public float length;
        public Vector3 boxThickness;
        public ParticleSystemMeshShapeType meshShapeType;
        public Mesh mesh;
        public MeshRenderer meshRenderer;
        public SkinnedMeshRenderer skinnedMeshRenderer;
        public Sprite sprite;
        public SpriteRenderer spriteRenderer;
        public bool useMeshMaterialIndex;
        public int meshMaterialIndex;
        public bool useMeshColors;
        public float normalOffset;
        public ParticleSystemShapeMultiModeValue meshSpawnMode;
        public float meshSpawnSpread;
        public MinMaxCurve meshSpawnSpeed;
        public float meshSpawnSpeedMultiplier;
        public float arc;
        public ParticleSystemShapeMultiModeValue arcMode;
        public float arcSpread;
        public MinMaxCurve arcSpeed;
        public float arcSpeedMultiplier;
        public float donutRadius;
        public Vector3 position;
        public Vector3 rotation;
        public Vector3 scale;
        public Texture2D texture;
        public ParticleSystemShapeTextureChannel textureClipChannel;
        public float textureClipThreshold;
        public bool textureColorAffectsParticles;
        public bool textureAlphaAffectsParticles;
        public bool textureBilinearFiltering;
        public int textureUVChannel;
    }

    [Serializable]
    public struct VelocityOverLifetimeModule
    {
        public bool enabled;
        public MinMaxCurve x;
        public MinMaxCurve y;
        public MinMaxCurve z;
        public float xMultiplier;
        public float yMultiplier;
        public float zMultiplier;
        public MinMaxCurve orbitalX;
        public MinMaxCurve orbitalY;
        public MinMaxCurve orbitalZ;
        public float orbitalXMultiplier;
        public float orbitalYMultiplier;
        public float orbitalZMultiplier;
        public MinMaxCurve orbitalOffsetX;
        public MinMaxCurve orbitalOffsetY;
        public MinMaxCurve orbitalOffsetZ;
        public float orbitalOffsetXMultiplier;
        public float orbitalOffsetYMultiplier;
        public float orbitalOffsetZMultiplier;
        public MinMaxCurve radial;
        public float radialMultiplier;
        public MinMaxCurve speedModifier;
        public float speedModifierMultiplier;
        public ParticleSystemSimulationSpace space;
    }

    [Serializable]
    public struct LimitVelocityOverLifetimeModule
    {
        public bool enabled;
        public MinMaxCurve limitX;
        public float limitXMultiplier;
        public MinMaxCurve limitY;
        public float limitYMultiplier;
        public MinMaxCurve limitZ;
        public float limitZMultiplier;
        public MinMaxCurve limit;
        public float limitMultiplier;
        public float dampen;
        public bool separateAxes;
        public ParticleSystemSimulationSpace space;
        public MinMaxCurve drag;
        public float dragMultiplier;
        public bool multiplyDragByParticleSize;
        public bool multiplyDragByParticleVelocity;
    }

    [Serializable]
    public struct InheritVelocityModule
    {
        public bool enabled;
        public ParticleSystemInheritVelocityMode mode;
        public MinMaxCurve curve;
        public float curveMultiplier;
    }

    [Serializable]
    public struct LifetimeByEmitterSpeedModule
    {
        public bool enabled;
        public MinMaxCurve curve;
        public float curveMultiplier;
        public Vector2 range;
    }

    [Serializable]
    public struct ForceOverLifetimeModule
    {
        public bool enabled;
        public MinMaxCurve x;
        public MinMaxCurve y;
        public MinMaxCurve z;
        public float xMultiplier;
        public float yMultiplier;
        public float zMultiplier;
        public ParticleSystemSimulationSpace space;
        public bool randomized;
    }

    [Serializable]
    public struct ColorOverLifetimeModule
    {
        public bool enabled;
        public MinMaxGradient color;
    }

    [Serializable]
    public struct ColorBySpeedModule
    {
        public bool enabled;
        public MinMaxGradient color;
        public Vector2 range;
    }

    [Serializable]
    public struct SizeOverLifetimeModule
    {
        public bool enabled;
        public MinMaxCurve size;
        public float sizeMultiplier;
        public MinMaxCurve x;
        public float xMultiplier;
        public MinMaxCurve y;
        public float yMultiplier;
        public MinMaxCurve z;
        public float zMultiplier;
        public bool separateAxes;
    }

    [Serializable]
    public struct SizeBySpeedModule
    {
        public bool enabled;
        public MinMaxCurve size;
        public float sizeMultiplier;
        public MinMaxCurve x;
        public float xMultiplier;
        public MinMaxCurve y;
        public float yMultiplier;
        public MinMaxCurve z;
        public float zMultiplier;
        public bool separateAxes;
        public Vector2 range;
    }

    [Serializable]
    public struct RotationOverLifetimeModule
    {
        public bool enabled;
        public MinMaxCurve x;
        public float xMultiplier;
        public MinMaxCurve y;
        public float yMultiplier;
        public MinMaxCurve z;
        public float zMultiplier;
        public bool separateAxes;
    }

    [Serializable]
    public struct RotationBySpeedModule
    {
        public bool enabled;
        public MinMaxCurve x;
        public float xMultiplier;
        public MinMaxCurve y;
        public float yMultiplier;
        public MinMaxCurve z;
        public float zMultiplier;
        public bool separateAxes;
        public Vector2 range;
    }

    [Serializable]
    public struct ExternalForcesModule
    {
        public bool enabled;
        public float multiplier;
        public MinMaxCurve multiplierCurve;
        public ParticleSystemGameObjectFilter influenceFilter;
        public LayerMask influenceMask;
    }

    [Serializable]
    public struct NoiseModule
    {
        public bool enabled;
        public bool separateAxes;
        public MinMaxCurve strength;
        public float strengthMultiplier;
        public MinMaxCurve strengthX;
        public float strengthXMultiplier;
        public MinMaxCurve strengthY;
        public float strengthYMultiplier;
        public MinMaxCurve strengthZ;
        public float strengthZMultiplier;
        public float frequency;
        public bool damping;
        public int octaveCount;
        public float octaveMultiplier;
        public float octaveScale;
        public ParticleSystemNoiseQuality quality;
        public MinMaxCurve scrollSpeed;
        public float scrollSpeedMultiplier;
        public bool remapEnabled;
        public MinMaxCurve remap;
        public float remapMultiplier;
        public MinMaxCurve remapX;
        public float remapXMultiplier;
        public MinMaxCurve remapY;
        public float remapYMultiplier;
        public MinMaxCurve remapZ;
        public float remapZMultiplier;
        public MinMaxCurve positionAmount;
        public MinMaxCurve rotationAmount;
        public MinMaxCurve sizeAmount;
    }

    [Serializable]
    public struct CollisionModule
    {
        public bool enabled;
        public ParticleSystemCollisionType type;
        public ParticleSystemCollisionMode mode;
        public MinMaxCurve dampen;
        public float dampenMultiplier;
        public MinMaxCurve bounce;
        public float bounceMultiplier;
        public MinMaxCurve lifetimeLoss;
        public float lifetimeLossMultiplier;
        public float minKillSpeed;
        public float maxKillSpeed;
        public LayerMask collidesWith;
        public bool enableDynamicColliders;
        public int maxCollisionShapes;
        public ParticleSystemCollisionQuality quality;
        public float voxelSize;
        public float radiusScale;
        public bool sendCollisionMessages;
        public float colliderForce;
        public bool multiplyColliderForceByCollisionAngle;
        public bool multiplyColliderForceByParticleSpeed;
        public bool multiplyColliderForceByParticleSize;
    }

    [Serializable]
    public struct TriggerModule
    {
        public bool enabled;
        public ParticleSystemOverlapAction inside;
        public ParticleSystemOverlapAction outside;
        public ParticleSystemOverlapAction enter;
        public ParticleSystemOverlapAction exit;
        public ParticleSystemColliderQueryMode colliderQueryMode;
        public float radiusScale;
    }

    [Serializable]
    public struct SubEmittersModule
    {
        public bool enabled;
    }

    [Serializable]
    public struct TextureSheetAnimationModule
    {
        public bool enabled;
        public ParticleSystemAnimationMode mode;
        public ParticleSystemAnimationTimeMode timeMode;
        public float fps;
        public int numTilesX;
        public int numTilesY;
        public ParticleSystemAnimationType animation;
        public ParticleSystemAnimationRowMode rowMode;
        public MinMaxCurve frameOverTime;
        public float frameOverTimeMultiplier;
        public MinMaxCurve startFrame;
        public float startFrameMultiplier;
        public int cycleCount;
        public int rowIndex;
        public UVChannelFlags uvChannelMask;
        public Vector2 speedRange;
    }

    [Serializable]
    public struct LightsModule
    {
        public bool enabled;
        public float ratio;
        public bool useRandomDistribution;
        public Light light;
        public bool useParticleColor;
        public bool sizeAffectsRange;
        public bool alphaAffectsIntensity;
        public MinMaxCurve range;
        public float rangeMultiplier;
        public MinMaxCurve intensity;
        public float intensityMultiplier;
        public int maxLights;
    }

    [Serializable]
    public struct TrailModule
    {
        public bool enabled;
        public ParticleSystemTrailMode mode;
        public float ratio;
        public MinMaxCurve lifetime;
        public float lifetimeMultiplier;
        public float minVertexDistance;
        public ParticleSystemTrailTextureMode textureMode;
        public bool worldSpace;
        public bool dieWithParticles;
        public bool sizeAffectsWidth;
        public bool sizeAffectsLifetime;
        public bool inheritParticleColor;
        public MinMaxGradient colorOverLifetime;
        public MinMaxCurve widthOverTrail;
        public float widthOverTrailMultiplier;
        public MinMaxGradient colorOverTrail;
        public bool generateLightingData;
        public int ribbonCount;
        public float shadowBias;
        public bool splitSubEmitterRibbons;
        public bool attachRibbonsToTransform;
    }

    [Serializable]
    public struct CustomDataModule
    {
        public bool enabled;
        public ParticleSystemCustomDataMode mode_1;
        public int vectorComponentCount_1;
        public MinMaxCurve[] VectorComponents_1;
        public MinMaxGradient color_1;

        public ParticleSystemCustomDataMode mode_2;
        public int vectorComponentCount_2;
        public MinMaxCurve[] VectorComponents_2;
        public MinMaxGradient color_2;
    }

    [Serializable]
    public struct Renderer
    {
        public bool enabled;
        public ParticleSystemRenderMode renderMode;
        public ParticleSystemRenderSpace alignment;
        public ParticleSystemSortMode sortMode;
        public float lengthScale;
        public float velocityScale;
        public float cameraVelocityScale;
        public float normalDirection;
        public float shadowBias;
        public float sortingFudge;
        public float minParticleSize;
        public float maxParticleSize;
        public Vector3 pivot;
        public Vector3 flip;
        public SpriteMaskInteraction maskInteraction;
        public Material trailMaterial;
        public bool enableGPUInstancing;
        public bool allowRoll;
        public bool freeformStretching;
        public bool rotateWithStretchDirection;
        public Mesh mesh;

        public Material sharedMaterial;
        public int sortingOrder;
        // public string sortingLayerName;
        public int sortingLayerID;
        public int rendererPriority;
        public uint renderingLayerMask;
        public List<ParticleSystemVertexStream> activeVertexStreams;
    }

    public static void RecordParticleSystemData(ParticleSystem ps, ParticleDummyData data)
    {
        data.time = ps.time;
        data.randomSeed = ps.randomSeed;
        data.useAutoRandomSeed = ps.useAutoRandomSeed;
        var main = ps.main;
        data.main.duration = main.duration;
        data.main.loop = main.loop;
        data.main.prewarm = main.prewarm;
        data.main.startDelay = main.startDelay;
        data.main.startDelayMultiplier = main.startDelayMultiplier;
        data.main.startLifetime = main.startLifetime;
        data.main.startLifetimeMultiplier = main.startLifetimeMultiplier;
        data.main.startSpeed = main.startSpeed;
        data.main.startSpeedMultiplier = main.startSpeedMultiplier;
        data.main.startSize3D = main.startSize3D;
        data.main.startSize = main.startSize;
        data.main.startSizeMultiplier = main.startSizeMultiplier;
        data.main.startSizeX = main.startSizeX;
        data.main.startSizeXMultiplier = main.startSizeXMultiplier;
        data.main.startSizeY = main.startSizeY;
        data.main.startSizeYMultiplier = main.startSizeYMultiplier;
        data.main.startSizeZ = main.startSizeZ;
        data.main.startSizeZMultiplier = main.startSizeZMultiplier;
        data.main.startRotation3D = main.startRotation3D;
        data.main.startRotation = main.startRotation;
        data.main.startRotationMultiplier = main.startRotationMultiplier;
        data.main.startRotationX = main.startRotationX;
        data.main.startRotationXMultiplier = main.startRotationXMultiplier;
        data.main.startRotationY = main.startRotationY;
        data.main.startRotationYMultiplier = main.startRotationYMultiplier;
        data.main.startRotationZ = main.startRotationZ;
        data.main.startRotationZMultiplier = main.startRotationZMultiplier;
        data.main.flipRotation = main.flipRotation;
        data.main.startColor = main.startColor;
        data.main.gravityModifier = main.gravityModifier;
        data.main.gravityModifierMultiplier = main.gravityModifierMultiplier;
        data.main.simulationSpace = main.simulationSpace;
        data.main.customSimulationSpace = main.customSimulationSpace;
        data.main.simulationSpeed = main.simulationSpeed;
        data.main.useUnscaledTime = main.useUnscaledTime;
        data.main.scalingMode = main.scalingMode;
        data.main.playOnAwake = main.playOnAwake;
        data.main.maxParticles = main.maxParticles;
        data.main.emitterVelocityMode = main.emitterVelocityMode;
        data.main.stopAction = main.stopAction;
        data.main.ringBufferMode = main.ringBufferMode;
        data.main.ringBufferLoopRange = main.ringBufferLoopRange;
        data.main.cullingMode = main.cullingMode;
        var emission = ps.emission;
        data.emission.enabled = emission.enabled;
        if (data.emission.enabled)
        {
            data.emission.rateOverTime = emission.rateOverTime;
            data.emission.rateOverTimeMultiplier = emission.rateOverTimeMultiplier;
            data.emission.rateOverDistance = emission.rateOverDistance;
            data.emission.rateOverDistanceMultiplier = emission.rateOverDistanceMultiplier;
            data.emission.burstCount = emission.burstCount;

            data.emission.bursts = new ParticleDummyData.Burst[emission.burstCount];
            for (int i = 0; i < emission.burstCount; i++)
            {
                var burst = emission.GetBurst(i);
                data.emission.bursts[i].time = burst.time;
                data.emission.bursts[i].count = burst.count;
                data.emission.bursts[i].cycleCount = burst.cycleCount;
                data.emission.bursts[i].repeatInterval = burst.repeatInterval;
                data.emission.bursts[i].probability = burst.probability;
            }
        }
        var shape = ps.shape;
        data.shape.enabled = shape.enabled;
        if (data.shape.enabled)
        {
            data.shape.shapeType = shape.shapeType;
            data.shape.randomDirectionAmount = shape.randomDirectionAmount;
            data.shape.sphericalDirectionAmount = shape.sphericalDirectionAmount;
            data.shape.randomPositionAmount = shape.randomPositionAmount;
            data.shape.alignToDirection = shape.alignToDirection;
            data.shape.radius = shape.radius;
            data.shape.radiusMode = shape.radiusMode;
            data.shape.radiusSpread = shape.radiusSpread;
            data.shape.radiusSpeed = shape.radiusSpeed;
            data.shape.radiusSpeedMultiplier = shape.radiusSpeedMultiplier;
            data.shape.radiusThickness = shape.radiusThickness;
            data.shape.angle = shape.angle;
            data.shape.length = shape.length;
            data.shape.boxThickness = shape.boxThickness;
            data.shape.meshShapeType = shape.meshShapeType;
            data.shape.mesh = shape.mesh;
            data.shape.meshRenderer = shape.meshRenderer;
            data.shape.skinnedMeshRenderer = shape.skinnedMeshRenderer;
            data.shape.sprite = shape.sprite;
            data.shape.spriteRenderer = shape.spriteRenderer;
            data.shape.useMeshMaterialIndex = shape.useMeshMaterialIndex;
            data.shape.meshMaterialIndex = shape.meshMaterialIndex;
            data.shape.useMeshColors = shape.useMeshColors;
            data.shape.normalOffset = shape.normalOffset;
            data.shape.meshSpawnMode = shape.meshSpawnMode;
            data.shape.meshSpawnSpread = shape.meshSpawnSpread;
            data.shape.meshSpawnSpeed = shape.meshSpawnSpeed;
            data.shape.meshSpawnSpeedMultiplier = shape.meshSpawnSpeedMultiplier;
            data.shape.arc = shape.arc;
            data.shape.arcMode = shape.arcMode;
            data.shape.arcSpread = shape.arcSpread;
            data.shape.arcSpeed = shape.arcSpeed;
            data.shape.arcSpeedMultiplier = shape.arcSpeedMultiplier;
            data.shape.donutRadius = shape.donutRadius;
            data.shape.position = shape.position;
            data.shape.rotation = shape.rotation;
            data.shape.scale = shape.scale;
            data.shape.texture = shape.texture;
            data.shape.textureClipChannel = shape.textureClipChannel;
            data.shape.textureClipThreshold = shape.textureClipThreshold;
            data.shape.textureColorAffectsParticles = shape.textureColorAffectsParticles;
            data.shape.textureAlphaAffectsParticles = shape.textureAlphaAffectsParticles;
            data.shape.textureBilinearFiltering = shape.textureBilinearFiltering;
            data.shape.textureUVChannel = shape.textureUVChannel;
        }
        var velocityOverLifetime = ps.velocityOverLifetime;
        data.velocityOverLifetime.enabled = velocityOverLifetime.enabled;
        if (data.velocityOverLifetime.enabled)
        {
            data.velocityOverLifetime.x = velocityOverLifetime.x;
            data.velocityOverLifetime.y = velocityOverLifetime.y;
            data.velocityOverLifetime.z = velocityOverLifetime.z;
            data.velocityOverLifetime.xMultiplier = velocityOverLifetime.xMultiplier;
            data.velocityOverLifetime.yMultiplier = velocityOverLifetime.yMultiplier;
            data.velocityOverLifetime.zMultiplier = velocityOverLifetime.zMultiplier;
            data.velocityOverLifetime.orbitalX = velocityOverLifetime.orbitalX;
            data.velocityOverLifetime.orbitalY = velocityOverLifetime.orbitalY;
            data.velocityOverLifetime.orbitalZ = velocityOverLifetime.orbitalZ;
            data.velocityOverLifetime.orbitalXMultiplier = velocityOverLifetime.orbitalXMultiplier;
            data.velocityOverLifetime.orbitalYMultiplier = velocityOverLifetime.orbitalYMultiplier;
            data.velocityOverLifetime.orbitalZMultiplier = velocityOverLifetime.orbitalZMultiplier;
            data.velocityOverLifetime.orbitalOffsetX = velocityOverLifetime.orbitalOffsetX;
            data.velocityOverLifetime.orbitalOffsetY = velocityOverLifetime.orbitalOffsetY;
            data.velocityOverLifetime.orbitalOffsetZ = velocityOverLifetime.orbitalOffsetZ;
            data.velocityOverLifetime.orbitalOffsetXMultiplier = velocityOverLifetime.orbitalOffsetXMultiplier;
            data.velocityOverLifetime.orbitalOffsetYMultiplier = velocityOverLifetime.orbitalOffsetYMultiplier;
            data.velocityOverLifetime.orbitalOffsetZMultiplier = velocityOverLifetime.orbitalOffsetZMultiplier;
            data.velocityOverLifetime.radial = velocityOverLifetime.radial;
            data.velocityOverLifetime.radialMultiplier = velocityOverLifetime.radialMultiplier;
            data.velocityOverLifetime.speedModifier = velocityOverLifetime.speedModifier;
            data.velocityOverLifetime.speedModifierMultiplier = velocityOverLifetime.speedModifierMultiplier;
            data.velocityOverLifetime.space = velocityOverLifetime.space;
        }
        var limitVelocityOverLifetime = ps.limitVelocityOverLifetime;
        data.limitVelocityOverLifetime.enabled = limitVelocityOverLifetime.enabled;
        if (data.limitVelocityOverLifetime.enabled)
        {
            data.limitVelocityOverLifetime.limitX = limitVelocityOverLifetime.limitX;
            data.limitVelocityOverLifetime.limitXMultiplier = limitVelocityOverLifetime.limitXMultiplier;
            data.limitVelocityOverLifetime.limitY = limitVelocityOverLifetime.limitY;
            data.limitVelocityOverLifetime.limitYMultiplier = limitVelocityOverLifetime.limitYMultiplier;
            data.limitVelocityOverLifetime.limitZ = limitVelocityOverLifetime.limitZ;
            data.limitVelocityOverLifetime.limitZMultiplier = limitVelocityOverLifetime.limitZMultiplier;
            data.limitVelocityOverLifetime.limit = limitVelocityOverLifetime.limit;
            data.limitVelocityOverLifetime.limitMultiplier = limitVelocityOverLifetime.limitMultiplier;
            data.limitVelocityOverLifetime.dampen = limitVelocityOverLifetime.dampen;
            data.limitVelocityOverLifetime.separateAxes = limitVelocityOverLifetime.separateAxes;
            data.limitVelocityOverLifetime.space = limitVelocityOverLifetime.space;
            data.limitVelocityOverLifetime.drag = limitVelocityOverLifetime.drag;
            data.limitVelocityOverLifetime.dragMultiplier = limitVelocityOverLifetime.dragMultiplier;
            data.limitVelocityOverLifetime.multiplyDragByParticleSize = limitVelocityOverLifetime.multiplyDragByParticleSize;
            data.limitVelocityOverLifetime.multiplyDragByParticleVelocity = limitVelocityOverLifetime.multiplyDragByParticleVelocity;
        }
        var inheritVelocity = ps.inheritVelocity;
        data.inheritVelocity.enabled = inheritVelocity.enabled;
        if (data.inheritVelocity.enabled)
        {
            data.inheritVelocity.mode = inheritVelocity.mode;
            data.inheritVelocity.curve = inheritVelocity.curve;
            data.inheritVelocity.curveMultiplier = inheritVelocity.curveMultiplier;
        }
        var lifetimeByEmitterSpeed = ps.lifetimeByEmitterSpeed;
        data.lifetimeByEmitterSpeed.enabled = lifetimeByEmitterSpeed.enabled;
        if (data.lifetimeByEmitterSpeed.enabled)
        {
            data.lifetimeByEmitterSpeed.curve = lifetimeByEmitterSpeed.curve;
            data.lifetimeByEmitterSpeed.curveMultiplier = lifetimeByEmitterSpeed.curveMultiplier;
            data.lifetimeByEmitterSpeed.range = lifetimeByEmitterSpeed.range;
        }
        var forceOverLifetime = ps.forceOverLifetime;
        data.forceOverLifetime.enabled = forceOverLifetime.enabled;
        if (data.forceOverLifetime.enabled)
        {
            data.forceOverLifetime.x = forceOverLifetime.x;
            data.forceOverLifetime.y = forceOverLifetime.y;
            data.forceOverLifetime.z = forceOverLifetime.z;
            data.forceOverLifetime.xMultiplier = forceOverLifetime.xMultiplier;
            data.forceOverLifetime.yMultiplier = forceOverLifetime.yMultiplier;
            data.forceOverLifetime.zMultiplier = forceOverLifetime.zMultiplier;
            data.forceOverLifetime.space = forceOverLifetime.space;
            data.forceOverLifetime.randomized = forceOverLifetime.randomized;
        }
        var colorOverLifetime = ps.colorOverLifetime;
        data.colorOverLifetime.enabled = colorOverLifetime.enabled;
        if (data.colorOverLifetime.enabled)
        {
            data.colorOverLifetime.color = colorOverLifetime.color;
        }
        var colorBySpeed = ps.colorBySpeed;
        data.colorBySpeed.enabled = colorBySpeed.enabled;
        if (data.colorBySpeed.enabled)
        {
            data.colorBySpeed.color = colorBySpeed.color;
            data.colorBySpeed.range = colorBySpeed.range;
        }
        var sizeOverLifetime = ps.sizeOverLifetime;
        data.sizeOverLifetime.enabled = sizeOverLifetime.enabled;
        if (data.sizeOverLifetime.enabled)
        {
            data.sizeOverLifetime.size = sizeOverLifetime.size;
            data.sizeOverLifetime.sizeMultiplier = sizeOverLifetime.sizeMultiplier;
            data.sizeOverLifetime.x = sizeOverLifetime.x;
            data.sizeOverLifetime.xMultiplier = sizeOverLifetime.xMultiplier;
            data.sizeOverLifetime.y = sizeOverLifetime.y;
            data.sizeOverLifetime.yMultiplier = sizeOverLifetime.yMultiplier;
            data.sizeOverLifetime.z = sizeOverLifetime.z;
            data.sizeOverLifetime.zMultiplier = sizeOverLifetime.zMultiplier;
            data.sizeOverLifetime.separateAxes = sizeOverLifetime.separateAxes;
        }
        var sizeBySpeed = ps.sizeBySpeed;
        data.sizeBySpeed.enabled = sizeBySpeed.enabled;
        if (data.sizeBySpeed.enabled)
        {
            data.sizeBySpeed.size = sizeBySpeed.size;
            data.sizeBySpeed.sizeMultiplier = sizeBySpeed.sizeMultiplier;
            data.sizeBySpeed.x = sizeBySpeed.x;
            data.sizeBySpeed.xMultiplier = sizeBySpeed.xMultiplier;
            data.sizeBySpeed.y = sizeBySpeed.y;
            data.sizeBySpeed.yMultiplier = sizeBySpeed.yMultiplier;
            data.sizeBySpeed.z = sizeBySpeed.z;
            data.sizeBySpeed.zMultiplier = sizeBySpeed.zMultiplier;
            data.sizeBySpeed.separateAxes = sizeBySpeed.separateAxes;
            data.sizeBySpeed.range = sizeBySpeed.range;
        }
        var rotationOverLifetime = ps.rotationOverLifetime;
        data.rotationOverLifetime.enabled = rotationOverLifetime.enabled;
        if (data.rotationOverLifetime.enabled)
        {
            data.rotationOverLifetime.x = rotationOverLifetime.x;
            data.rotationOverLifetime.xMultiplier = rotationOverLifetime.xMultiplier;
            data.rotationOverLifetime.y = rotationOverLifetime.y;
            data.rotationOverLifetime.yMultiplier = rotationOverLifetime.yMultiplier;
            data.rotationOverLifetime.z = rotationOverLifetime.z;
            data.rotationOverLifetime.zMultiplier = rotationOverLifetime.zMultiplier;
            data.rotationOverLifetime.separateAxes = rotationOverLifetime.separateAxes;
        }
        var rotationBySpeed = ps.rotationBySpeed;
        data.rotationBySpeed.enabled = rotationBySpeed.enabled;
        if (data.rotationBySpeed.enabled)
        {
            data.rotationBySpeed.x = rotationBySpeed.x;
            data.rotationBySpeed.xMultiplier = rotationBySpeed.xMultiplier;
            data.rotationBySpeed.y = rotationBySpeed.y;
            data.rotationBySpeed.yMultiplier = rotationBySpeed.yMultiplier;
            data.rotationBySpeed.z = rotationBySpeed.z;
            data.rotationBySpeed.zMultiplier = rotationBySpeed.zMultiplier;
            data.rotationBySpeed.separateAxes = rotationBySpeed.separateAxes;
            data.rotationBySpeed.range = rotationBySpeed.range;
        }
        var externalForces = ps.externalForces;
        data.externalForces.enabled = externalForces.enabled;
        if (data.externalForces.enabled)
        {
            data.externalForces.multiplier = externalForces.multiplier;
            data.externalForces.multiplierCurve = externalForces.multiplierCurve;
            data.externalForces.influenceFilter = externalForces.influenceFilter;
            data.externalForces.influenceMask = externalForces.influenceMask;
        }
        var noise = ps.noise;
        data.noise.enabled = noise.enabled;
        if (data.noise.enabled)
        {
            data.noise.separateAxes = noise.separateAxes;
            data.noise.strength = noise.strength;
            data.noise.strengthMultiplier = noise.strengthMultiplier;
            data.noise.strengthX = noise.strengthX;
            data.noise.strengthXMultiplier = noise.strengthXMultiplier;
            data.noise.strengthY = noise.strengthY;
            data.noise.strengthYMultiplier = noise.strengthYMultiplier;
            data.noise.strengthZ = noise.strengthZ;
            data.noise.strengthZMultiplier = noise.strengthZMultiplier;
            data.noise.frequency = noise.frequency;
            data.noise.damping = noise.damping;
            data.noise.octaveCount = noise.octaveCount;
            data.noise.octaveMultiplier = noise.octaveMultiplier;
            data.noise.octaveScale = noise.octaveScale;
            data.noise.quality = noise.quality;
            data.noise.scrollSpeed = noise.scrollSpeed;
            data.noise.scrollSpeedMultiplier = noise.scrollSpeedMultiplier;
            data.noise.remapEnabled = noise.remapEnabled;
            data.noise.remap = noise.remap;
            data.noise.remapMultiplier = noise.remapMultiplier;
            data.noise.remapX = noise.remapX;
            data.noise.remapXMultiplier = noise.remapXMultiplier;
            data.noise.remapY = noise.remapY;
            data.noise.remapYMultiplier = noise.remapYMultiplier;
            data.noise.remapZ = noise.remapZ;
            data.noise.remapZMultiplier = noise.remapZMultiplier;
            data.noise.positionAmount = noise.positionAmount;
            data.noise.rotationAmount = noise.rotationAmount;
            data.noise.sizeAmount = noise.sizeAmount;
        }
        var collision = ps.collision;
        data.collision.enabled = collision.enabled;
        if (data.collision.enabled)
        {
            data.collision.type = collision.type;
            data.collision.mode = collision.mode;
            data.collision.dampen = collision.dampen;
            data.collision.dampenMultiplier = collision.dampenMultiplier;
            data.collision.bounce = collision.bounce;
            data.collision.bounceMultiplier = collision.bounceMultiplier;
            data.collision.lifetimeLoss = collision.lifetimeLoss;
            data.collision.lifetimeLossMultiplier = collision.lifetimeLossMultiplier;
            data.collision.minKillSpeed = collision.minKillSpeed;
            data.collision.maxKillSpeed = collision.maxKillSpeed;
            data.collision.collidesWith = collision.collidesWith;
            data.collision.enableDynamicColliders = collision.enableDynamicColliders;
            data.collision.maxCollisionShapes = collision.maxCollisionShapes;
            data.collision.quality = collision.quality;
            data.collision.voxelSize = collision.voxelSize;
            data.collision.radiusScale = collision.radiusScale;
            data.collision.sendCollisionMessages = collision.sendCollisionMessages;
            data.collision.colliderForce = collision.colliderForce;
            data.collision.multiplyColliderForceByCollisionAngle = collision.multiplyColliderForceByCollisionAngle;
            data.collision.multiplyColliderForceByParticleSpeed = collision.multiplyColliderForceByParticleSpeed;
            data.collision.multiplyColliderForceByParticleSize = collision.multiplyColliderForceByParticleSize;
        }
        var trigger = ps.trigger;
        data.trigger.enabled = trigger.enabled;
        if (data.trigger.enabled)
        {
            data.trigger.inside = trigger.inside;
            data.trigger.outside = trigger.outside;
            data.trigger.enter = trigger.enter;
            data.trigger.exit = trigger.exit;
            data.trigger.colliderQueryMode = trigger.colliderQueryMode;
            data.trigger.radiusScale = trigger.radiusScale;
        }
        data.subEmitters.enabled = ps.subEmitters.enabled;
        if (data.subEmitters.enabled)
        {
            throw new System.Exception($"ParticleSystemDummy do not support subEmitters, {ps.gameObject}");
        }
        var textureSheetAnimation = ps.textureSheetAnimation;
        data.textureSheetAnimation.enabled = textureSheetAnimation.enabled;
        if (data.textureSheetAnimation.enabled)
        {
            data.textureSheetAnimation.mode = textureSheetAnimation.mode;
            data.textureSheetAnimation.timeMode = textureSheetAnimation.timeMode;
            data.textureSheetAnimation.fps = textureSheetAnimation.fps;
            data.textureSheetAnimation.numTilesX = textureSheetAnimation.numTilesX;
            data.textureSheetAnimation.numTilesY = textureSheetAnimation.numTilesY;
            data.textureSheetAnimation.animation = textureSheetAnimation.animation;
            data.textureSheetAnimation.rowMode = textureSheetAnimation.rowMode;
            data.textureSheetAnimation.frameOverTime = textureSheetAnimation.frameOverTime;
            data.textureSheetAnimation.frameOverTimeMultiplier = textureSheetAnimation.frameOverTimeMultiplier;
            data.textureSheetAnimation.startFrame = textureSheetAnimation.startFrame;
            data.textureSheetAnimation.startFrameMultiplier = textureSheetAnimation.startFrameMultiplier;
            data.textureSheetAnimation.cycleCount = textureSheetAnimation.cycleCount;
            data.textureSheetAnimation.rowIndex = textureSheetAnimation.rowIndex;
            data.textureSheetAnimation.uvChannelMask = textureSheetAnimation.uvChannelMask;
            data.textureSheetAnimation.speedRange = textureSheetAnimation.speedRange;
        }
        var lights = ps.lights;
        data.lights.enabled = lights.enabled;
        if (data.lights.enabled)
        {
            data.lights.ratio = lights.ratio;
            data.lights.useRandomDistribution = lights.useRandomDistribution;
            data.lights.light = lights.light;
            data.lights.useParticleColor = lights.useParticleColor;
            data.lights.sizeAffectsRange = lights.sizeAffectsRange;
            data.lights.alphaAffectsIntensity = lights.alphaAffectsIntensity;
            data.lights.range = lights.range;
            data.lights.rangeMultiplier = lights.rangeMultiplier;
            data.lights.intensity = lights.intensity;
            data.lights.intensityMultiplier = lights.intensityMultiplier;
            data.lights.maxLights = lights.maxLights;
        }
        var trails = ps.trails;
        data.trails.enabled = trails.enabled;
        if (data.trails.enabled)
        {
            data.trails.mode = trails.mode;
            data.trails.ratio = trails.ratio;
            data.trails.lifetime = trails.lifetime;
            data.trails.lifetimeMultiplier = trails.lifetimeMultiplier;
            data.trails.minVertexDistance = trails.minVertexDistance;
            data.trails.textureMode = trails.textureMode;
            data.trails.worldSpace = trails.worldSpace;
            data.trails.dieWithParticles = trails.dieWithParticles;
            data.trails.sizeAffectsWidth = trails.sizeAffectsWidth;
            data.trails.sizeAffectsLifetime = trails.sizeAffectsLifetime;
            data.trails.inheritParticleColor = trails.inheritParticleColor;
            data.trails.colorOverLifetime = trails.colorOverLifetime;
            data.trails.widthOverTrail = trails.widthOverTrail;
            data.trails.widthOverTrailMultiplier = trails.widthOverTrailMultiplier;
            data.trails.colorOverTrail = trails.colorOverTrail;
            data.trails.generateLightingData = trails.generateLightingData;
            data.trails.ribbonCount = trails.ribbonCount;
            data.trails.shadowBias = trails.shadowBias;
            data.trails.splitSubEmitterRibbons = trails.splitSubEmitterRibbons;
            data.trails.attachRibbonsToTransform = trails.attachRibbonsToTransform;
        }
        data.customData.enabled = ps.customData.enabled;
        if (data.customData.enabled)
        {
            data.customData.mode_1 = ps.customData.GetMode(ParticleSystemCustomData.Custom1);
            data.customData.color_1 = ps.customData.GetColor(ParticleSystemCustomData.Custom1);
            data.customData.vectorComponentCount_1 = ps.customData.GetVectorComponentCount(ParticleSystemCustomData.Custom1);
            if (data.customData.VectorComponents_1 == null || data.customData.VectorComponents_1.Length != data.customData.vectorComponentCount_1)
            {
                data.customData.VectorComponents_1 = new MinMaxCurve[data.customData.vectorComponentCount_1];
            }
            for (int i = 0; i < data.customData.vectorComponentCount_1; i++)
            {
                data.customData.VectorComponents_1[i] = ps.customData.GetVector(ParticleSystemCustomData.Custom1, i);
            }

            data.customData.mode_2 = ps.customData.GetMode(ParticleSystemCustomData.Custom2);
            data.customData.color_2 = ps.customData.GetColor(ParticleSystemCustomData.Custom2);
            data.customData.vectorComponentCount_2 = ps.customData.GetVectorComponentCount(ParticleSystemCustomData.Custom2);
            if (data.customData.VectorComponents_2 == null || data.customData.VectorComponents_2.Length != data.customData.vectorComponentCount_2)
            {
                data.customData.VectorComponents_2 = new MinMaxCurve[data.customData.vectorComponentCount_2];
            }
            for (int i = 0; i < data.customData.vectorComponentCount_2; i++)
            {
                data.customData.VectorComponents_2[i] = ps.customData.GetVector(ParticleSystemCustomData.Custom2, i);
            }
        }
        var renderer = ps.GetComponent<ParticleSystemRenderer>();
        data.renderer.enabled = renderer.enabled;
        // 不论renderer是否enable，都要记录数据
        {
            data.renderer.renderMode = renderer.renderMode;
            data.renderer.alignment = renderer.alignment;
            data.renderer.sortMode = renderer.sortMode;
            data.renderer.lengthScale = renderer.lengthScale;
            data.renderer.velocityScale = renderer.velocityScale;
            data.renderer.cameraVelocityScale = renderer.cameraVelocityScale;
            data.renderer.normalDirection = renderer.normalDirection;
            data.renderer.shadowBias = renderer.shadowBias;
            data.renderer.sortingFudge = renderer.sortingFudge;
            data.renderer.minParticleSize = renderer.minParticleSize;
            data.renderer.maxParticleSize = renderer.maxParticleSize;
            data.renderer.pivot = renderer.pivot;
            data.renderer.flip = renderer.flip;
            data.renderer.maskInteraction = renderer.maskInteraction;
            data.renderer.trailMaterial = renderer.trailMaterial;
            data.renderer.enableGPUInstancing = renderer.enableGPUInstancing;
            data.renderer.allowRoll = renderer.allowRoll;
            data.renderer.freeformStretching = renderer.freeformStretching;
            data.renderer.rotateWithStretchDirection = renderer.rotateWithStretchDirection;
            data.renderer.mesh = renderer.mesh;

            data.renderer.sharedMaterial = renderer.sharedMaterial;
            data.renderer.sortingOrder = renderer.sortingOrder;
            // data.renderer.sortingLayerName = renderer.sortingLayerName;
            data.renderer.sortingLayerID = renderer.sortingLayerID;
            data.renderer.rendererPriority = renderer.rendererPriority;
            data.renderer.renderingLayerMask = renderer.renderingLayerMask;
            data.renderer.activeVertexStreams = new List<ParticleSystemVertexStream>(10); // 预分配10个，一般只会用到4-6个
            renderer.GetActiveVertexStreams(data.renderer.activeVertexStreams);
        }
    }

    public static void ApplyParticleSystemData(ParticleSystem ps, ParticleSystemRenderer particleSystemRenderer, ParticleDummyData data)
    {
        // 赋值比取值更耗，所以先对比确认需不需要赋值
        if (ps.time != data.time) ps.time = data.time;
        if (ps.randomSeed != data.randomSeed) ps.randomSeed = data.randomSeed;
        if (ps.useAutoRandomSeed != data.useAutoRandomSeed) ps.useAutoRandomSeed = data.useAutoRandomSeed;
        var main = ps.main;
        if (main.duration != data.main.duration) main.duration = data.main.duration;
        if (main.loop != data.main.loop) main.loop = data.main.loop;
        if (main.prewarm != data.main.prewarm) main.prewarm = data.main.prewarm;
        main.startDelay = data.main.startDelay;
        if (main.startDelayMultiplier != data.main.startDelayMultiplier) main.startDelayMultiplier = data.main.startDelayMultiplier;
        main.startLifetime = data.main.startLifetime;
        if (main.startLifetimeMultiplier != data.main.startLifetimeMultiplier) main.startLifetimeMultiplier = data.main.startLifetimeMultiplier;
        main.startSpeed = data.main.startSpeed;
        if (main.startSpeedMultiplier != data.main.startSpeedMultiplier) main.startSpeedMultiplier = data.main.startSpeedMultiplier;
        if (main.startSize3D != data.main.startSize3D) main.startSize3D = data.main.startSize3D;
        main.startSize = data.main.startSize;
        if (main.startSizeMultiplier != data.main.startSizeMultiplier) main.startSizeMultiplier = data.main.startSizeMultiplier;
        main.startSizeX = data.main.startSizeX;
        if (main.startSizeXMultiplier != data.main.startSizeXMultiplier) main.startSizeXMultiplier = data.main.startSizeXMultiplier;
        main.startSizeY = data.main.startSizeY;
        if (main.startSizeYMultiplier != data.main.startSizeYMultiplier) main.startSizeYMultiplier = data.main.startSizeYMultiplier;
        main.startSizeZ = data.main.startSizeZ;
        if (main.startSizeZMultiplier != data.main.startSizeZMultiplier) main.startSizeZMultiplier = data.main.startSizeZMultiplier;
        if (main.startRotation3D != data.main.startRotation3D) main.startRotation3D = data.main.startRotation3D;
        main.startRotation = data.main.startRotation;
        if (main.startRotationMultiplier != data.main.startRotationMultiplier) main.startRotationMultiplier = data.main.startRotationMultiplier;
        main.startRotationX = data.main.startRotationX;
        if (main.startRotationXMultiplier != data.main.startRotationXMultiplier) main.startRotationXMultiplier = data.main.startRotationXMultiplier;
        main.startRotationY = data.main.startRotationY;
        if (main.startRotationYMultiplier != data.main.startRotationYMultiplier) main.startRotationYMultiplier = data.main.startRotationYMultiplier;
        main.startRotationZ = data.main.startRotationZ;
        if (main.startRotationZMultiplier != data.main.startRotationZMultiplier) main.startRotationZMultiplier = data.main.startRotationZMultiplier;
        if (main.flipRotation != data.main.flipRotation) main.flipRotation = data.main.flipRotation;
        main.startColor = data.main.startColor;
        main.gravityModifier = data.main.gravityModifier;
        if (main.gravityModifierMultiplier != data.main.gravityModifierMultiplier) main.gravityModifierMultiplier = data.main.gravityModifierMultiplier;
        if (main.simulationSpace != data.main.simulationSpace) main.simulationSpace = data.main.simulationSpace;
        if (main.customSimulationSpace != data.main.customSimulationSpace) main.customSimulationSpace = data.main.customSimulationSpace;
        if (main.simulationSpeed != data.main.simulationSpeed) main.simulationSpeed = data.main.simulationSpeed;
        if (main.useUnscaledTime != data.main.useUnscaledTime) main.useUnscaledTime = data.main.useUnscaledTime;
        if (main.scalingMode != data.main.scalingMode) main.scalingMode = data.main.scalingMode;
        if (main.playOnAwake != data.main.playOnAwake) main.playOnAwake = data.main.playOnAwake;
        if (main.maxParticles != data.main.maxParticles) main.maxParticles = data.main.maxParticles;
        if (main.emitterVelocityMode != data.main.emitterVelocityMode) main.emitterVelocityMode = data.main.emitterVelocityMode;
        if (main.stopAction != data.main.stopAction) main.stopAction = data.main.stopAction;
        if (main.ringBufferMode != data.main.ringBufferMode) main.ringBufferMode = data.main.ringBufferMode;
        if (main.ringBufferLoopRange != data.main.ringBufferLoopRange) main.ringBufferLoopRange = data.main.ringBufferLoopRange;
        if (main.cullingMode != data.main.cullingMode) main.cullingMode = data.main.cullingMode;
        var emission = ps.emission;
        if (emission.enabled != data.emission.enabled) emission.enabled = data.emission.enabled;
        if (emission.enabled)
        {
            emission.rateOverTime = data.emission.rateOverTime;
            if (emission.rateOverTimeMultiplier != data.emission.rateOverTimeMultiplier) emission.rateOverTimeMultiplier = data.emission.rateOverTimeMultiplier;
            emission.rateOverDistance = data.emission.rateOverDistance;
            if (emission.rateOverDistanceMultiplier != data.emission.rateOverDistanceMultiplier) emission.rateOverDistanceMultiplier = data.emission.rateOverDistanceMultiplier;
            if (emission.burstCount != data.emission.burstCount) emission.burstCount = data.emission.burstCount;
            for (int i = 0; i < data.emission.burstCount; i++)
            {
                var burstData = data.emission.bursts[i];
                var b = new ParticleSystem.Burst()
                {
                    time = burstData.time,
                    count = burstData.count,
                    cycleCount = burstData.cycleCount,
                    repeatInterval = burstData.repeatInterval,
                    probability = burstData.probability
                };
                emission.SetBurst(i, b);
            }
        }

        var shape = ps.shape;
        if (shape.enabled != data.shape.enabled) shape.enabled = data.shape.enabled;
        if (shape.enabled)
        {
            if (shape.shapeType != data.shape.shapeType) shape.shapeType = data.shape.shapeType;
            if (shape.randomDirectionAmount != data.shape.randomDirectionAmount) shape.randomDirectionAmount = data.shape.randomDirectionAmount;
            if (shape.sphericalDirectionAmount != data.shape.sphericalDirectionAmount) shape.sphericalDirectionAmount = data.shape.sphericalDirectionAmount;
            if (shape.randomPositionAmount != data.shape.randomPositionAmount) shape.randomPositionAmount = data.shape.randomPositionAmount;
            if (shape.alignToDirection != data.shape.alignToDirection) shape.alignToDirection = data.shape.alignToDirection;
            if (shape.radius != data.shape.radius) shape.radius = data.shape.radius;
            if (shape.radiusMode != data.shape.radiusMode) shape.radiusMode = data.shape.radiusMode;
            if (shape.radiusSpread != data.shape.radiusSpread) shape.radiusSpread = data.shape.radiusSpread;
            shape.radiusSpeed = data.shape.radiusSpeed;
            if (shape.radiusSpeedMultiplier != data.shape.radiusSpeedMultiplier) shape.radiusSpeedMultiplier = data.shape.radiusSpeedMultiplier;
            if (shape.radiusThickness != data.shape.radiusThickness) shape.radiusThickness = data.shape.radiusThickness;
            if (shape.angle != data.shape.angle) shape.angle = data.shape.angle;
            if (shape.length != data.shape.length) shape.length = data.shape.length;
            if (shape.boxThickness != data.shape.boxThickness) shape.boxThickness = data.shape.boxThickness;
            if (shape.meshShapeType != data.shape.meshShapeType) shape.meshShapeType = data.shape.meshShapeType;
            if (shape.mesh != data.shape.mesh) shape.mesh = data.shape.mesh;
            if (shape.meshRenderer != data.shape.meshRenderer) shape.meshRenderer = data.shape.meshRenderer;
            if (shape.skinnedMeshRenderer != data.shape.skinnedMeshRenderer) shape.skinnedMeshRenderer = data.shape.skinnedMeshRenderer;
            if (shape.sprite != data.shape.sprite) shape.sprite = data.shape.sprite;
            if (shape.spriteRenderer != data.shape.spriteRenderer) shape.spriteRenderer = data.shape.spriteRenderer;
            if (shape.useMeshMaterialIndex != data.shape.useMeshMaterialIndex) shape.useMeshMaterialIndex = data.shape.useMeshMaterialIndex;
            if (shape.meshMaterialIndex != data.shape.meshMaterialIndex) shape.meshMaterialIndex = data.shape.meshMaterialIndex;
            if (shape.useMeshColors != data.shape.useMeshColors) shape.useMeshColors = data.shape.useMeshColors;
            if (shape.normalOffset != data.shape.normalOffset) shape.normalOffset = data.shape.normalOffset;
            if (shape.meshSpawnMode != data.shape.meshSpawnMode) shape.meshSpawnMode = data.shape.meshSpawnMode;
            if (shape.meshSpawnSpread != data.shape.meshSpawnSpread) shape.meshSpawnSpread = data.shape.meshSpawnSpread;
            shape.meshSpawnSpeed = data.shape.meshSpawnSpeed;
            if (shape.meshSpawnSpeedMultiplier != data.shape.meshSpawnSpeedMultiplier) shape.meshSpawnSpeedMultiplier = data.shape.meshSpawnSpeedMultiplier;
            if (shape.arc != data.shape.arc) shape.arc = data.shape.arc;
            if (shape.arcMode != data.shape.arcMode) shape.arcMode = data.shape.arcMode;
            if (shape.arcSpread != data.shape.arcSpread) shape.arcSpread = data.shape.arcSpread;
            shape.arcSpeed = data.shape.arcSpeed;
            if (shape.arcSpeedMultiplier != data.shape.arcSpeedMultiplier) shape.arcSpeedMultiplier = data.shape.arcSpeedMultiplier;
            if (shape.donutRadius != data.shape.donutRadius) shape.donutRadius = data.shape.donutRadius;
            if (shape.position != data.shape.position) shape.position = data.shape.position;
            if (shape.rotation != data.shape.rotation) shape.rotation = data.shape.rotation;
            if (shape.scale != data.shape.scale) shape.scale = data.shape.scale;
            if (shape.texture != data.shape.texture) shape.texture = data.shape.texture;
            if (shape.textureClipChannel != data.shape.textureClipChannel) shape.textureClipChannel = data.shape.textureClipChannel;
            if (shape.textureClipThreshold != data.shape.textureClipThreshold) shape.textureClipThreshold = data.shape.textureClipThreshold;
            if (shape.textureColorAffectsParticles != data.shape.textureColorAffectsParticles) shape.textureColorAffectsParticles = data.shape.textureColorAffectsParticles;
            if (shape.textureAlphaAffectsParticles != data.shape.textureAlphaAffectsParticles) shape.textureAlphaAffectsParticles = data.shape.textureAlphaAffectsParticles;
            if (shape.textureBilinearFiltering != data.shape.textureBilinearFiltering) shape.textureBilinearFiltering = data.shape.textureBilinearFiltering;
            if (shape.textureUVChannel != data.shape.textureUVChannel) shape.textureUVChannel = data.shape.textureUVChannel;
        }
        var velocityOverLifetime = ps.velocityOverLifetime;
        if (velocityOverLifetime.enabled != data.velocityOverLifetime.enabled) velocityOverLifetime.enabled = data.velocityOverLifetime.enabled;
        if (velocityOverLifetime.enabled)
        {
            velocityOverLifetime.x = data.velocityOverLifetime.x;
            velocityOverLifetime.y = data.velocityOverLifetime.y;
            velocityOverLifetime.z = data.velocityOverLifetime.z;
            if (velocityOverLifetime.xMultiplier != data.velocityOverLifetime.xMultiplier) velocityOverLifetime.xMultiplier = data.velocityOverLifetime.xMultiplier;
            if (velocityOverLifetime.yMultiplier != data.velocityOverLifetime.yMultiplier) velocityOverLifetime.yMultiplier = data.velocityOverLifetime.yMultiplier;
            if (velocityOverLifetime.zMultiplier != data.velocityOverLifetime.zMultiplier) velocityOverLifetime.zMultiplier = data.velocityOverLifetime.zMultiplier;
            velocityOverLifetime.orbitalX = data.velocityOverLifetime.orbitalX;
            velocityOverLifetime.orbitalY = data.velocityOverLifetime.orbitalY;
            velocityOverLifetime.orbitalZ = data.velocityOverLifetime.orbitalZ;
            if (velocityOverLifetime.orbitalXMultiplier != data.velocityOverLifetime.orbitalXMultiplier) velocityOverLifetime.orbitalXMultiplier = data.velocityOverLifetime.orbitalXMultiplier;
            if (velocityOverLifetime.orbitalYMultiplier != data.velocityOverLifetime.orbitalYMultiplier) velocityOverLifetime.orbitalYMultiplier = data.velocityOverLifetime.orbitalYMultiplier;
            if (velocityOverLifetime.orbitalZMultiplier != data.velocityOverLifetime.orbitalZMultiplier) velocityOverLifetime.orbitalZMultiplier = data.velocityOverLifetime.orbitalZMultiplier;
            velocityOverLifetime.orbitalOffsetX = data.velocityOverLifetime.orbitalOffsetX;
            velocityOverLifetime.orbitalOffsetY = data.velocityOverLifetime.orbitalOffsetY;
            velocityOverLifetime.orbitalOffsetZ = data.velocityOverLifetime.orbitalOffsetZ;
            if (velocityOverLifetime.orbitalOffsetXMultiplier != data.velocityOverLifetime.orbitalOffsetXMultiplier) velocityOverLifetime.orbitalOffsetXMultiplier = data.velocityOverLifetime.orbitalOffsetXMultiplier;
            if (velocityOverLifetime.orbitalOffsetYMultiplier != data.velocityOverLifetime.orbitalOffsetYMultiplier) velocityOverLifetime.orbitalOffsetYMultiplier = data.velocityOverLifetime.orbitalOffsetYMultiplier;
            if (velocityOverLifetime.orbitalOffsetZMultiplier != data.velocityOverLifetime.orbitalOffsetZMultiplier) velocityOverLifetime.orbitalOffsetZMultiplier = data.velocityOverLifetime.orbitalOffsetZMultiplier;
            velocityOverLifetime.radial = data.velocityOverLifetime.radial;
            if (velocityOverLifetime.radialMultiplier != data.velocityOverLifetime.radialMultiplier) velocityOverLifetime.radialMultiplier = data.velocityOverLifetime.radialMultiplier;
            velocityOverLifetime.speedModifier = data.velocityOverLifetime.speedModifier;
            if (velocityOverLifetime.speedModifierMultiplier != data.velocityOverLifetime.speedModifierMultiplier) velocityOverLifetime.speedModifierMultiplier = data.velocityOverLifetime.speedModifierMultiplier;
            if (velocityOverLifetime.space != data.velocityOverLifetime.space) velocityOverLifetime.space = data.velocityOverLifetime.space;
        }
        var limitVelocityOverLifetime = ps.limitVelocityOverLifetime;
        if (limitVelocityOverLifetime.enabled != data.limitVelocityOverLifetime.enabled) limitVelocityOverLifetime.enabled = data.limitVelocityOverLifetime.enabled;
        if (limitVelocityOverLifetime.enabled)
        {
            limitVelocityOverLifetime.limitX = data.limitVelocityOverLifetime.limitX;
            if (limitVelocityOverLifetime.limitXMultiplier != data.limitVelocityOverLifetime.limitXMultiplier) limitVelocityOverLifetime.limitXMultiplier = data.limitVelocityOverLifetime.limitXMultiplier;
            limitVelocityOverLifetime.limitY = data.limitVelocityOverLifetime.limitY;
            if (limitVelocityOverLifetime.limitYMultiplier != data.limitVelocityOverLifetime.limitYMultiplier) limitVelocityOverLifetime.limitYMultiplier = data.limitVelocityOverLifetime.limitYMultiplier;
            limitVelocityOverLifetime.limitZ = data.limitVelocityOverLifetime.limitZ;
            if (limitVelocityOverLifetime.limitZMultiplier != data.limitVelocityOverLifetime.limitZMultiplier) limitVelocityOverLifetime.limitZMultiplier = data.limitVelocityOverLifetime.limitZMultiplier;
            limitVelocityOverLifetime.limit = data.limitVelocityOverLifetime.limit;
            if (limitVelocityOverLifetime.limitMultiplier != data.limitVelocityOverLifetime.limitMultiplier) limitVelocityOverLifetime.limitMultiplier = data.limitVelocityOverLifetime.limitMultiplier;
            if (limitVelocityOverLifetime.dampen != data.limitVelocityOverLifetime.dampen) limitVelocityOverLifetime.dampen = data.limitVelocityOverLifetime.dampen;
            if (limitVelocityOverLifetime.separateAxes != data.limitVelocityOverLifetime.separateAxes) limitVelocityOverLifetime.separateAxes = data.limitVelocityOverLifetime.separateAxes;
            if (limitVelocityOverLifetime.space != data.limitVelocityOverLifetime.space) limitVelocityOverLifetime.space = data.limitVelocityOverLifetime.space;
            limitVelocityOverLifetime.drag = data.limitVelocityOverLifetime.drag;
            if (limitVelocityOverLifetime.dragMultiplier != data.limitVelocityOverLifetime.dragMultiplier) limitVelocityOverLifetime.dragMultiplier = data.limitVelocityOverLifetime.dragMultiplier;
            if (limitVelocityOverLifetime.multiplyDragByParticleSize != data.limitVelocityOverLifetime.multiplyDragByParticleSize) limitVelocityOverLifetime.multiplyDragByParticleSize = data.limitVelocityOverLifetime.multiplyDragByParticleSize;
            if (limitVelocityOverLifetime.multiplyDragByParticleVelocity != data.limitVelocityOverLifetime.multiplyDragByParticleVelocity) limitVelocityOverLifetime.multiplyDragByParticleVelocity = data.limitVelocityOverLifetime.multiplyDragByParticleVelocity;
        }
        var inheritVelocity = ps.inheritVelocity;
        if (inheritVelocity.enabled != data.inheritVelocity.enabled) inheritVelocity.enabled = data.inheritVelocity.enabled;
        if (inheritVelocity.enabled)
        {
            if (inheritVelocity.mode != data.inheritVelocity.mode) inheritVelocity.mode = data.inheritVelocity.mode;
            inheritVelocity.curve = data.inheritVelocity.curve;
            if (inheritVelocity.curveMultiplier != data.inheritVelocity.curveMultiplier) inheritVelocity.curveMultiplier = data.inheritVelocity.curveMultiplier;
        }
        var lifetimeByEmitterSpeed = ps.lifetimeByEmitterSpeed;
        if (lifetimeByEmitterSpeed.enabled != data.lifetimeByEmitterSpeed.enabled) lifetimeByEmitterSpeed.enabled = data.lifetimeByEmitterSpeed.enabled;
        if (lifetimeByEmitterSpeed.enabled)
        {
            lifetimeByEmitterSpeed.curve = data.lifetimeByEmitterSpeed.curve;
            if (lifetimeByEmitterSpeed.curveMultiplier != data.lifetimeByEmitterSpeed.curveMultiplier) lifetimeByEmitterSpeed.curveMultiplier = data.lifetimeByEmitterSpeed.curveMultiplier;
            if (lifetimeByEmitterSpeed.range != data.lifetimeByEmitterSpeed.range) lifetimeByEmitterSpeed.range = data.lifetimeByEmitterSpeed.range;
        }
        var forceOverLifetime = ps.forceOverLifetime;
        if (forceOverLifetime.enabled != data.forceOverLifetime.enabled) forceOverLifetime.enabled = data.forceOverLifetime.enabled;
        if (forceOverLifetime.enabled)
        {
            forceOverLifetime.x = data.forceOverLifetime.x;
            forceOverLifetime.y = data.forceOverLifetime.y;
            forceOverLifetime.z = data.forceOverLifetime.z;
            if (forceOverLifetime.xMultiplier != data.forceOverLifetime.xMultiplier) forceOverLifetime.xMultiplier = data.forceOverLifetime.xMultiplier;
            if (forceOverLifetime.yMultiplier != data.forceOverLifetime.yMultiplier) forceOverLifetime.yMultiplier = data.forceOverLifetime.yMultiplier;
            if (forceOverLifetime.zMultiplier != data.forceOverLifetime.zMultiplier) forceOverLifetime.zMultiplier = data.forceOverLifetime.zMultiplier;
            if (forceOverLifetime.space != data.forceOverLifetime.space) forceOverLifetime.space = data.forceOverLifetime.space;
            if (forceOverLifetime.randomized != data.forceOverLifetime.randomized) forceOverLifetime.randomized = data.forceOverLifetime.randomized;
        }
        var colorOverLifetime = ps.colorOverLifetime;
        if (colorOverLifetime.enabled != data.colorOverLifetime.enabled) colorOverLifetime.enabled = data.colorOverLifetime.enabled;
        if (colorOverLifetime.enabled)
        {
            colorOverLifetime.color = data.colorOverLifetime.color;
        }
        var colorBySpeed = ps.colorBySpeed;
        if (colorBySpeed.enabled != data.colorBySpeed.enabled) colorBySpeed.enabled = data.colorBySpeed.enabled;
        if (colorBySpeed.enabled)
        {
            colorBySpeed.color = data.colorBySpeed.color;
            if (colorBySpeed.range != data.colorBySpeed.range) colorBySpeed.range = data.colorBySpeed.range;
        }
        var sizeOverLifetime = ps.sizeOverLifetime;
        if (sizeOverLifetime.enabled != data.sizeOverLifetime.enabled) sizeOverLifetime.enabled = data.sizeOverLifetime.enabled;
        if (sizeOverLifetime.enabled)
        {
            sizeOverLifetime.size = data.sizeOverLifetime.size;
            if (sizeOverLifetime.sizeMultiplier != data.sizeOverLifetime.sizeMultiplier) sizeOverLifetime.sizeMultiplier = data.sizeOverLifetime.sizeMultiplier;
            sizeOverLifetime.x = data.sizeOverLifetime.x;
            if (sizeOverLifetime.xMultiplier != data.sizeOverLifetime.xMultiplier) sizeOverLifetime.xMultiplier = data.sizeOverLifetime.xMultiplier;
            sizeOverLifetime.y = data.sizeOverLifetime.y;
            if (sizeOverLifetime.yMultiplier != data.sizeOverLifetime.yMultiplier) sizeOverLifetime.yMultiplier = data.sizeOverLifetime.yMultiplier;
            sizeOverLifetime.z = data.sizeOverLifetime.z;
            if (sizeOverLifetime.zMultiplier != data.sizeOverLifetime.zMultiplier) sizeOverLifetime.zMultiplier = data.sizeOverLifetime.zMultiplier;
            if (sizeOverLifetime.separateAxes != data.sizeOverLifetime.separateAxes) sizeOverLifetime.separateAxes = data.sizeOverLifetime.separateAxes;
        }
        var sizeBySpeed = ps.sizeBySpeed;
        if (sizeBySpeed.enabled != data.sizeBySpeed.enabled) sizeBySpeed.enabled = data.sizeBySpeed.enabled;
        if (sizeBySpeed.enabled)
        {
            sizeBySpeed.size = data.sizeBySpeed.size;
            if (sizeBySpeed.sizeMultiplier != data.sizeBySpeed.sizeMultiplier) sizeBySpeed.sizeMultiplier = data.sizeBySpeed.sizeMultiplier;
            sizeBySpeed.x = data.sizeBySpeed.x;
            if (sizeBySpeed.xMultiplier != data.sizeBySpeed.xMultiplier) sizeBySpeed.xMultiplier = data.sizeBySpeed.xMultiplier;
            sizeBySpeed.y = data.sizeBySpeed.y;
            if (sizeBySpeed.yMultiplier != data.sizeBySpeed.yMultiplier) sizeBySpeed.yMultiplier = data.sizeBySpeed.yMultiplier;
            sizeBySpeed.z = data.sizeBySpeed.z;
            if (sizeBySpeed.zMultiplier != data.sizeBySpeed.zMultiplier) sizeBySpeed.zMultiplier = data.sizeBySpeed.zMultiplier;
            if (sizeBySpeed.separateAxes != data.sizeBySpeed.separateAxes) sizeBySpeed.separateAxes = data.sizeBySpeed.separateAxes;
            if (sizeBySpeed.range != data.sizeBySpeed.range) sizeBySpeed.range = data.sizeBySpeed.range;
        }
        var rotationOverLifetime = ps.rotationOverLifetime;
        if (rotationOverLifetime.enabled != data.rotationOverLifetime.enabled) rotationOverLifetime.enabled = data.rotationOverLifetime.enabled;
        if (rotationOverLifetime.enabled)
        {
            rotationOverLifetime.x = data.rotationOverLifetime.x;
            if (rotationOverLifetime.xMultiplier != data.rotationOverLifetime.xMultiplier) rotationOverLifetime.xMultiplier = data.rotationOverLifetime.xMultiplier;
            rotationOverLifetime.y = data.rotationOverLifetime.y;
            if (rotationOverLifetime.yMultiplier != data.rotationOverLifetime.yMultiplier) rotationOverLifetime.yMultiplier = data.rotationOverLifetime.yMultiplier;
            rotationOverLifetime.z = data.rotationOverLifetime.z;
            if (rotationOverLifetime.zMultiplier != data.rotationOverLifetime.zMultiplier) rotationOverLifetime.zMultiplier = data.rotationOverLifetime.zMultiplier;
            if (rotationOverLifetime.separateAxes != data.rotationOverLifetime.separateAxes) rotationOverLifetime.separateAxes = data.rotationOverLifetime.separateAxes;
        }
        var rotationBySpeed = ps.rotationBySpeed;
        if (rotationBySpeed.enabled != data.rotationBySpeed.enabled) rotationBySpeed.enabled = data.rotationBySpeed.enabled;
        if (rotationBySpeed.enabled)
        {
            rotationBySpeed.x = data.rotationBySpeed.x;
            if (rotationBySpeed.xMultiplier != data.rotationBySpeed.xMultiplier) rotationBySpeed.xMultiplier = data.rotationBySpeed.xMultiplier;
            rotationBySpeed.y = data.rotationBySpeed.y;
            if (rotationBySpeed.yMultiplier != data.rotationBySpeed.yMultiplier) rotationBySpeed.yMultiplier = data.rotationBySpeed.yMultiplier;
            rotationBySpeed.z = data.rotationBySpeed.z;
            if (rotationBySpeed.zMultiplier != data.rotationBySpeed.zMultiplier) rotationBySpeed.zMultiplier = data.rotationBySpeed.zMultiplier;
            if (rotationBySpeed.separateAxes != data.rotationBySpeed.separateAxes) rotationBySpeed.separateAxes = data.rotationBySpeed.separateAxes;
            if (rotationBySpeed.range != data.rotationBySpeed.range) rotationBySpeed.range = data.rotationBySpeed.range;
        }
        var externalForces = ps.externalForces;
        if (externalForces.enabled != data.externalForces.enabled) externalForces.enabled = data.externalForces.enabled;
        if (externalForces.enabled)
        {
            if (externalForces.multiplier != data.externalForces.multiplier) externalForces.multiplier = data.externalForces.multiplier;
            externalForces.multiplierCurve = data.externalForces.multiplierCurve;
            if (externalForces.influenceFilter != data.externalForces.influenceFilter) externalForces.influenceFilter = data.externalForces.influenceFilter;
            if (externalForces.influenceMask != data.externalForces.influenceMask) externalForces.influenceMask = data.externalForces.influenceMask;
        }
        var noise = ps.noise;
        if (noise.enabled != data.noise.enabled) noise.enabled = data.noise.enabled;
        if (noise.enabled)
        {
            if (noise.separateAxes != data.noise.separateAxes) noise.separateAxes = data.noise.separateAxes;
            noise.strength = data.noise.strength;
            if (noise.strengthMultiplier != data.noise.strengthMultiplier) noise.strengthMultiplier = data.noise.strengthMultiplier;
            noise.strengthX = data.noise.strengthX;
            if (noise.strengthXMultiplier != data.noise.strengthXMultiplier) noise.strengthXMultiplier = data.noise.strengthXMultiplier;
            noise.strengthY = data.noise.strengthY;
            if (noise.strengthYMultiplier != data.noise.strengthYMultiplier) noise.strengthYMultiplier = data.noise.strengthYMultiplier;
            noise.strengthZ = data.noise.strengthZ;
            if (noise.strengthZMultiplier != data.noise.strengthZMultiplier) noise.strengthZMultiplier = data.noise.strengthZMultiplier;
            if (noise.frequency != data.noise.frequency) noise.frequency = data.noise.frequency;
            if (noise.damping != data.noise.damping) noise.damping = data.noise.damping;
            if (noise.octaveCount != data.noise.octaveCount) noise.octaveCount = data.noise.octaveCount;
            if (noise.octaveMultiplier != data.noise.octaveMultiplier) noise.octaveMultiplier = data.noise.octaveMultiplier;
            if (noise.octaveScale != data.noise.octaveScale) noise.octaveScale = data.noise.octaveScale;
            if (noise.quality != data.noise.quality) noise.quality = data.noise.quality;
            noise.scrollSpeed = data.noise.scrollSpeed;
            if (noise.scrollSpeedMultiplier != data.noise.scrollSpeedMultiplier) noise.scrollSpeedMultiplier = data.noise.scrollSpeedMultiplier;
            if (noise.remapEnabled != data.noise.remapEnabled) noise.remapEnabled = data.noise.remapEnabled;
            noise.remap = data.noise.remap;
            if (noise.remapMultiplier != data.noise.remapMultiplier) noise.remapMultiplier = data.noise.remapMultiplier;
            noise.remapX = data.noise.remapX;
            if (noise.remapXMultiplier != data.noise.remapXMultiplier) noise.remapXMultiplier = data.noise.remapXMultiplier;
            noise.remapY = data.noise.remapY;
            if (noise.remapYMultiplier != data.noise.remapYMultiplier) noise.remapYMultiplier = data.noise.remapYMultiplier;
            noise.remapZ = data.noise.remapZ;
            if (noise.remapZMultiplier != data.noise.remapZMultiplier) noise.remapZMultiplier = data.noise.remapZMultiplier;
            noise.positionAmount = data.noise.positionAmount;
            noise.rotationAmount = data.noise.rotationAmount;
            noise.sizeAmount = data.noise.sizeAmount;
        }
        var collision = ps.collision;
        if (collision.enabled != data.collision.enabled) collision.enabled = data.collision.enabled;
        if (collision.enabled)
        {
            if (collision.type != data.collision.type) collision.type = data.collision.type;
            if (collision.mode != data.collision.mode) collision.mode = data.collision.mode;
            collision.dampen = data.collision.dampen;
            if (collision.dampenMultiplier != data.collision.dampenMultiplier) collision.dampenMultiplier = data.collision.dampenMultiplier;
            collision.bounce = data.collision.bounce;
            if (collision.bounceMultiplier != data.collision.bounceMultiplier) collision.bounceMultiplier = data.collision.bounceMultiplier;
            collision.lifetimeLoss = data.collision.lifetimeLoss;
            if (collision.lifetimeLossMultiplier != data.collision.lifetimeLossMultiplier) collision.lifetimeLossMultiplier = data.collision.lifetimeLossMultiplier;
            if (collision.minKillSpeed != data.collision.minKillSpeed) collision.minKillSpeed = data.collision.minKillSpeed;
            if (collision.maxKillSpeed != data.collision.maxKillSpeed) collision.maxKillSpeed = data.collision.maxKillSpeed;
            if (collision.collidesWith != data.collision.collidesWith) collision.collidesWith = data.collision.collidesWith;
            if (collision.enableDynamicColliders != data.collision.enableDynamicColliders) collision.enableDynamicColliders = data.collision.enableDynamicColliders;
            if (collision.maxCollisionShapes != data.collision.maxCollisionShapes) collision.maxCollisionShapes = data.collision.maxCollisionShapes;
            if (collision.quality != data.collision.quality) collision.quality = data.collision.quality;
            if (collision.voxelSize != data.collision.voxelSize) collision.voxelSize = data.collision.voxelSize;
            if (collision.radiusScale != data.collision.radiusScale) collision.radiusScale = data.collision.radiusScale;
            if (collision.sendCollisionMessages != data.collision.sendCollisionMessages) collision.sendCollisionMessages = data.collision.sendCollisionMessages;
            if (collision.colliderForce != data.collision.colliderForce) collision.colliderForce = data.collision.colliderForce;
            if (collision.multiplyColliderForceByCollisionAngle != data.collision.multiplyColliderForceByCollisionAngle) collision.multiplyColliderForceByCollisionAngle = data.collision.multiplyColliderForceByCollisionAngle;
            if (collision.multiplyColliderForceByParticleSpeed != data.collision.multiplyColliderForceByParticleSpeed) collision.multiplyColliderForceByParticleSpeed = data.collision.multiplyColliderForceByParticleSpeed;
            if (collision.multiplyColliderForceByParticleSize != data.collision.multiplyColliderForceByParticleSize) collision.multiplyColliderForceByParticleSize = data.collision.multiplyColliderForceByParticleSize;
        }
        var trigger = ps.trigger;
        if (trigger.enabled != data.trigger.enabled) trigger.enabled = data.trigger.enabled;
        if (trigger.enabled)
        {
            if (trigger.inside != data.trigger.inside) trigger.inside = data.trigger.inside;
            if (trigger.outside != data.trigger.outside) trigger.outside = data.trigger.outside;
            if (trigger.enter != data.trigger.enter) trigger.enter = data.trigger.enter;
            if (trigger.exit != data.trigger.exit) trigger.exit = data.trigger.exit;
            if (trigger.colliderQueryMode != data.trigger.colliderQueryMode) trigger.colliderQueryMode = data.trigger.colliderQueryMode;
            if (trigger.radiusScale != data.trigger.radiusScale) trigger.radiusScale = data.trigger.radiusScale;
        }
        var subEmitters = ps.subEmitters;
        if (subEmitters.enabled != data.subEmitters.enabled) subEmitters.enabled = data.subEmitters.enabled;
        if (subEmitters.enabled)
        {
            throw new System.Exception($"ParticleSystemDummy do not support subEmitters, {ps.gameObject}");
        }
        var textureSheetAnimation = ps.textureSheetAnimation;
        if (textureSheetAnimation.enabled != data.textureSheetAnimation.enabled) textureSheetAnimation.enabled = data.textureSheetAnimation.enabled;
        if (textureSheetAnimation.enabled)
        {
            if (textureSheetAnimation.mode != data.textureSheetAnimation.mode) textureSheetAnimation.mode = data.textureSheetAnimation.mode;
            if (textureSheetAnimation.timeMode != data.textureSheetAnimation.timeMode) textureSheetAnimation.timeMode = data.textureSheetAnimation.timeMode;
            if (textureSheetAnimation.fps != data.textureSheetAnimation.fps) textureSheetAnimation.fps = data.textureSheetAnimation.fps;
            if (textureSheetAnimation.numTilesX != data.textureSheetAnimation.numTilesX) textureSheetAnimation.numTilesX = data.textureSheetAnimation.numTilesX;
            if (textureSheetAnimation.numTilesY != data.textureSheetAnimation.numTilesY) textureSheetAnimation.numTilesY = data.textureSheetAnimation.numTilesY;
            if (textureSheetAnimation.animation != data.textureSheetAnimation.animation) textureSheetAnimation.animation = data.textureSheetAnimation.animation;
            if (textureSheetAnimation.rowMode != data.textureSheetAnimation.rowMode) textureSheetAnimation.rowMode = data.textureSheetAnimation.rowMode;
            textureSheetAnimation.frameOverTime = data.textureSheetAnimation.frameOverTime;
            if (textureSheetAnimation.frameOverTimeMultiplier != data.textureSheetAnimation.frameOverTimeMultiplier) textureSheetAnimation.frameOverTimeMultiplier = data.textureSheetAnimation.frameOverTimeMultiplier;
            textureSheetAnimation.startFrame = data.textureSheetAnimation.startFrame;
            if (textureSheetAnimation.startFrameMultiplier != data.textureSheetAnimation.startFrameMultiplier) textureSheetAnimation.startFrameMultiplier = data.textureSheetAnimation.startFrameMultiplier;
            if (textureSheetAnimation.cycleCount != data.textureSheetAnimation.cycleCount) textureSheetAnimation.cycleCount = data.textureSheetAnimation.cycleCount;
            if (textureSheetAnimation.rowIndex != data.textureSheetAnimation.rowIndex) textureSheetAnimation.rowIndex = data.textureSheetAnimation.rowIndex;
            if (textureSheetAnimation.uvChannelMask != data.textureSheetAnimation.uvChannelMask) textureSheetAnimation.uvChannelMask = data.textureSheetAnimation.uvChannelMask;
            if (textureSheetAnimation.speedRange != data.textureSheetAnimation.speedRange) textureSheetAnimation.speedRange = data.textureSheetAnimation.speedRange;
        }
        var lights = ps.lights;
        if (lights.enabled != data.lights.enabled) lights.enabled = data.lights.enabled;
        if (lights.enabled)
        {
            if (lights.ratio != data.lights.ratio) lights.ratio = data.lights.ratio;
            if (lights.useRandomDistribution != data.lights.useRandomDistribution) lights.useRandomDistribution = data.lights.useRandomDistribution;
            if (lights.light != data.lights.light) lights.light = data.lights.light;
            if (lights.useParticleColor != data.lights.useParticleColor) lights.useParticleColor = data.lights.useParticleColor;
            if (lights.sizeAffectsRange != data.lights.sizeAffectsRange) lights.sizeAffectsRange = data.lights.sizeAffectsRange;
            if (lights.alphaAffectsIntensity != data.lights.alphaAffectsIntensity) lights.alphaAffectsIntensity = data.lights.alphaAffectsIntensity;
            lights.range = data.lights.range;
            if (lights.rangeMultiplier != data.lights.rangeMultiplier) lights.rangeMultiplier = data.lights.rangeMultiplier;
            lights.intensity = data.lights.intensity;
            if (lights.intensityMultiplier != data.lights.intensityMultiplier) lights.intensityMultiplier = data.lights.intensityMultiplier;
            if (lights.maxLights != data.lights.maxLights) lights.maxLights = data.lights.maxLights;
        }
        var trails = ps.trails;
        if (trails.enabled != data.trails.enabled) trails.enabled = data.trails.enabled;
        if (trails.enabled)
        {
            if (trails.mode != data.trails.mode) trails.mode = data.trails.mode;
            if (trails.ratio != data.trails.ratio) trails.ratio = data.trails.ratio;
            trails.lifetime = data.trails.lifetime;
            if (trails.lifetimeMultiplier != data.trails.lifetimeMultiplier) trails.lifetimeMultiplier = data.trails.lifetimeMultiplier;
            if (trails.minVertexDistance != data.trails.minVertexDistance) trails.minVertexDistance = data.trails.minVertexDistance;
            if (trails.textureMode != data.trails.textureMode) trails.textureMode = data.trails.textureMode;
            if (trails.worldSpace != data.trails.worldSpace) trails.worldSpace = data.trails.worldSpace;
            if (trails.dieWithParticles != data.trails.dieWithParticles) trails.dieWithParticles = data.trails.dieWithParticles;
            if (trails.sizeAffectsWidth != data.trails.sizeAffectsWidth) trails.sizeAffectsWidth = data.trails.sizeAffectsWidth;
            if (trails.sizeAffectsLifetime != data.trails.sizeAffectsLifetime) trails.sizeAffectsLifetime = data.trails.sizeAffectsLifetime;
            if (trails.inheritParticleColor != data.trails.inheritParticleColor) trails.inheritParticleColor = data.trails.inheritParticleColor;
            trails.colorOverLifetime = data.trails.colorOverLifetime;
            trails.widthOverTrail = data.trails.widthOverTrail;
            if (trails.widthOverTrailMultiplier != data.trails.widthOverTrailMultiplier) trails.widthOverTrailMultiplier = data.trails.widthOverTrailMultiplier;
            trails.colorOverTrail = data.trails.colorOverTrail;
            if (trails.generateLightingData != data.trails.generateLightingData) trails.generateLightingData = data.trails.generateLightingData;
            if (trails.ribbonCount != data.trails.ribbonCount) trails.ribbonCount = data.trails.ribbonCount;
            if (trails.shadowBias != data.trails.shadowBias) trails.shadowBias = data.trails.shadowBias;
            if (trails.splitSubEmitterRibbons != data.trails.splitSubEmitterRibbons) trails.splitSubEmitterRibbons = data.trails.splitSubEmitterRibbons;
            if (trails.attachRibbonsToTransform != data.trails.attachRibbonsToTransform) trails.attachRibbonsToTransform = data.trails.attachRibbonsToTransform;
        }
        var customData = ps.customData;
        if (customData.enabled != data.customData.enabled) customData.enabled = data.customData.enabled;
        if (customData.enabled)
        {
            customData.SetMode(ParticleSystemCustomData.Custom1, data.customData.mode_1);
            customData.SetColor(ParticleSystemCustomData.Custom1, data.customData.color_1);
            customData.SetVectorComponentCount(ParticleSystemCustomData.Custom1, data.customData.vectorComponentCount_1);
            if (data.customData.VectorComponents_1 != null && data.customData.VectorComponents_1.Length > 0)
            {
                for (int i = 0; i < data.customData.vectorComponentCount_1; i++)
                {
                    customData.SetVector(ParticleSystemCustomData.Custom1, i, data.customData.VectorComponents_1[i]);
                }
            }

            customData.SetMode(ParticleSystemCustomData.Custom2, data.customData.mode_2);
            customData.SetColor(ParticleSystemCustomData.Custom2, data.customData.color_2);
            customData.SetVectorComponentCount(ParticleSystemCustomData.Custom2, data.customData.vectorComponentCount_2);
            if (data.customData.VectorComponents_2 != null && data.customData.VectorComponents_2.Length > 0)
            {
                for (int i = 0; i < data.customData.vectorComponentCount_2; i++)
                {
                    customData.SetVector(ParticleSystemCustomData.Custom2, i, data.customData.VectorComponents_2[i]);
                }
            }
        }

        if (particleSystemRenderer.enabled != data.renderer.enabled) particleSystemRenderer.enabled = data.renderer.enabled;
        // 不论是否enabled，Renderer的属性都需要赋值
        {
            if (particleSystemRenderer.renderMode != data.renderer.renderMode) particleSystemRenderer.renderMode = data.renderer.renderMode;
            if (particleSystemRenderer.alignment != data.renderer.alignment) particleSystemRenderer.alignment = data.renderer.alignment;
            if (particleSystemRenderer.sortMode != data.renderer.sortMode) particleSystemRenderer.sortMode = data.renderer.sortMode;
            if (particleSystemRenderer.lengthScale != data.renderer.lengthScale) particleSystemRenderer.lengthScale = data.renderer.lengthScale;
            if (particleSystemRenderer.velocityScale != data.renderer.velocityScale) particleSystemRenderer.velocityScale = data.renderer.velocityScale;
            if (particleSystemRenderer.cameraVelocityScale != data.renderer.cameraVelocityScale) particleSystemRenderer.cameraVelocityScale = data.renderer.cameraVelocityScale;
            if (particleSystemRenderer.normalDirection != data.renderer.normalDirection) particleSystemRenderer.normalDirection = data.renderer.normalDirection;
            if (particleSystemRenderer.shadowBias != data.renderer.shadowBias) particleSystemRenderer.shadowBias = data.renderer.shadowBias;
            if (particleSystemRenderer.sortingFudge != data.renderer.sortingFudge) particleSystemRenderer.sortingFudge = data.renderer.sortingFudge;
            if (particleSystemRenderer.minParticleSize != data.renderer.minParticleSize) particleSystemRenderer.minParticleSize = data.renderer.minParticleSize;
            if (particleSystemRenderer.maxParticleSize != data.renderer.maxParticleSize) particleSystemRenderer.maxParticleSize = data.renderer.maxParticleSize;
            if (particleSystemRenderer.pivot != data.renderer.pivot) particleSystemRenderer.pivot = data.renderer.pivot;
            if (particleSystemRenderer.flip != data.renderer.flip) particleSystemRenderer.flip = data.renderer.flip;
            if (particleSystemRenderer.maskInteraction != data.renderer.maskInteraction) particleSystemRenderer.maskInteraction = data.renderer.maskInteraction;
            if (particleSystemRenderer.trailMaterial != data.renderer.trailMaterial) particleSystemRenderer.trailMaterial = data.renderer.trailMaterial;
            if (particleSystemRenderer.enableGPUInstancing != data.renderer.enableGPUInstancing) particleSystemRenderer.enableGPUInstancing = data.renderer.enableGPUInstancing;
            if (particleSystemRenderer.allowRoll != data.renderer.allowRoll) particleSystemRenderer.allowRoll = data.renderer.allowRoll;
            if (particleSystemRenderer.freeformStretching != data.renderer.freeformStretching) particleSystemRenderer.freeformStretching = data.renderer.freeformStretching;
            if (particleSystemRenderer.rotateWithStretchDirection != data.renderer.rotateWithStretchDirection) particleSystemRenderer.rotateWithStretchDirection = data.renderer.rotateWithStretchDirection;
            if (particleSystemRenderer.mesh != data.renderer.mesh) particleSystemRenderer.mesh = data.renderer.mesh;

            // 这些是基类Renderer的属性
            if (particleSystemRenderer.sharedMaterial != data.renderer.sharedMaterial) particleSystemRenderer.sharedMaterial = data.renderer.sharedMaterial;
            if (particleSystemRenderer.sortingOrder != data.renderer.sortingOrder) particleSystemRenderer.sortingOrder = data.renderer.sortingOrder;
            // if (particleSystemRenderer.sortingLayerName != data.renderer.sortingLayerName) particleSystemRenderer.sortingLayerName = data.renderer.sortingLayerName;
            if (particleSystemRenderer.sortingLayerID != data.renderer.sortingLayerID) particleSystemRenderer.sortingLayerID = data.renderer.sortingLayerID;
            if (particleSystemRenderer.rendererPriority != data.renderer.rendererPriority) particleSystemRenderer.rendererPriority = data.renderer.rendererPriority;
            if (particleSystemRenderer.renderingLayerMask != data.renderer.renderingLayerMask) particleSystemRenderer.renderingLayerMask = data.renderer.renderingLayerMask;

            particleSystemRenderer.SetActiveVertexStreams(data.renderer.activeVertexStreams);
            
            // 下面这些用在粒子系统上时应该是不需要的
            // 不能使用material或materials赋值，因为会导致材质复制
            // currentRender.material = particleRenderer.material;
            // currentRender.materials = particleRenderer.materials;

            // 获取sharedMaterials还挺耗时的，会产生新的数组导致GC，而且看起来并不需要。sharedMaterial应该足够了。
            // currentRender.sharedMaterials = particleRenderer.sharedMaterials; 

            // currentRender.reflectionProbeUsage = particleRenderer.reflectionProbeUsage;
            // currentRender.lightProbeUsage = particleRenderer.lightProbeUsage;
            // currentRender.motionVectorGenerationMode = particleRenderer.motionVectorGenerationMode;
            // currentRender.forceRenderingOff = particleRenderer.forceRenderingOff;
            // currentRender.receiveShadows = particleRenderer.receiveShadows;
            // currentRender.shadowCastingMode = particleRenderer.shadowCastingMode;
            // currentRender.rayTracingMode = particleRenderer.rayTracingMode;
            // currentRender.allowOcclusionWhenDynamic = particleRenderer.allowOcclusionWhenDynamic;
            // currentRender.lightProbeProxyVolumeOverride = particleRenderer.lightProbeProxyVolumeOverride;
            // currentRender.probeAnchor = particleRenderer.probeAnchor;
            // currentRender.lightmapIndex = particleRenderer.lightmapIndex;
            // currentRender.realtimeLightmapIndex = particleRenderer.realtimeLightmapIndex;
            // currentRender.lightmapScaleOffset = particleRenderer.lightmapScaleOffset;
            // currentRender.realtimeLightmapScaleOffset = particleRenderer.realtimeLightmapScaleOffset;
        }
    }

}